//
//  HSYBaseQRCodeViewController.m
//  高仿暴走斗图
//
//  Created by key on 16/3/23.
//  Copyright © 2016年 huangsongyao. All rights reserved.
//

#import "HSYBaseQRCodeViewController.h"
#import <AVFoundation/AVFoundation.h>
#import "UIImage+Canvas.h"
#import "HSYBaseQRCodeViewController+Manager.h"
#import "HSYBaseQRCodeViewController+UI.h"
#import "NSObject+CreateControls.h"
#import "HSYBaseViewController+Device.h"

#define CONTENT_WIDTH       (IPHONE_WIDTH-30)
#define IMG_TAG             88774

@interface HSYBaseQRCodeViewController ()<AVCaptureMetadataOutputObjectsDelegate>

@property (nonatomic, strong) AVCaptureSession * session;                   //输入输出的中间桥梁
@property (nonatomic, strong) AVCaptureDevice * device;                     //摄像头设备
@property (nonatomic, strong) AVCaptureDeviceInput * input;                 //输入流
@property (nonatomic, strong) AVCaptureMetadataOutput * output;             //输出流
@property (nonatomic, strong) AVCaptureVideoPreviewLayer * previewLayer;    //图象渲染层

@property (nonatomic, strong) UIImageView *scanLayer;                       //扫描线
@property (nonatomic, assign) BOOL isCreateQRCodeCamera;                    //是否创建了二维码相机

@end
@implementation HSYBaseQRCodeViewController

- (instancetype)init {
    
    if (self = [super init]) {
        
        [self setup];
    }
    return self;
}

- (void)setup {
    self.title = HSYLOCALIZED(@"二维码扫描");
    self.view.backgroundColor = [UIColor blackColor];
}

- (void)viewDidLoad {
    
    [super viewDidLoad];
    
    CGFloat x = 60.0f;
    CGFloat y = 140;
    CGFloat size = CGRectGetWidth(self.view.bounds) - x *2;
    CGRect rect = CGRectMake(x, y, size, size);
    _boxRect = rect;
    //创建UI
    [self addQRCodeUIWithRect:rect];
}

- (void)viewDidAppear:(BOOL)animated {
    
    [super viewDidAppear:animated];
    if (!self.isCreateQRCodeCamera) {
        [self stopACtivityIndicatorViewInParentView:self.boxView];
        if ([self isCamera]) {
            //如果可以调用摄像头则创建设备连接，初始化二维码相机
            [self addQRCodeCameraInterfaceWithBoxViewRect:_boxRect];
            self.isCreateQRCodeCamera = YES;
        }
    }
}

- (void)dealloc {
    [self stopRunning];                 //关闭二维码相机扫描
}


#pragma mark - UI

- (void)addQRCodeUIWithRect:(CGRect)rect {
    
    //添加中空的背景图
    [self statScanningAnimationTimerWithCropRect:rect];
    //扫描框
    _boxView = [self createBoxViewWithFrame:rect borderColor:CLEAR_COLOR borderWidth:1.0f];
    [self.view addSubview:self.boxView];
    
    //扫描线
    self.scanLayer = [self createScanLayerWithFrame:CGRectMake(rect.origin.x, rect.origin.y, CGRectGetWidth(self.boxView.frame), 1) image:QRCODE_SCANNING_LINE];
    [self.view.layer addSublayer:self.scanLayer.layer];
    [self.view addSubview:self.scanLayer];
    
    
    //开启扫描动画
    [self starScanningAnimation];
    [self showActivityIndicatorViewInParentView:self.boxView];//菊花loading
}

- (void)statScanningAnimationTimerWithCropRect:(CGRect)cropRect {
    
    UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage drawQRCodeBackgroundImageWithReferenceRect:self.view.bounds cropRect:cropRect alpha:0.0f]];
    imageView.tag = IMG_TAG;
    imageView.frame = self.view.bounds;
    [self.view addSubview:imageView];
}

- (UIView *)createBoxViewWithFrame:(CGRect)frame borderColor:(UIColor *)borderColor borderWidth:(CGFloat)borderWidth {
    
    UIView  *boxView = [[UIView alloc] initWithFrame:frame];
    boxView.layer.borderColor = borderColor.CGColor;    //线框颜色
    boxView.layer.borderWidth = borderWidth;            //线框线的宽度
    
    UIImageView *boxImage = [self createScanLayerWithFrame:boxView.bounds image:QRCODE_SCANNING_BG];
    [boxView addSubview:boxImage];
    
    return boxView;
}

- (UIImageView *)createScanLayerWithFrame:(CGRect)frame image:(NSString *)image {
    
    UIImageView *scanLayerImage = [NSObject createImgWithImage:CREATE_IMG(image)
                                                        hImage:CREATE_IMG(image)
                                                 clipsToBounds:YES
                                                       vcModel:UIViewContentModeScaleToFill];
    scanLayerImage.frame = frame;
    
    return scanLayerImage;
}


- (void)starScanningAnimation {
    
    CGFloat y = CGRectGetHeight(self.boxView.frame);
    [self starQRCodeAnimationInLayer:self.scanLayer.layer toY:@(y) completion:^() {
    }];
}

- (void)stopScanningAnimation {
    
    [self removeQRCodeAnimationInLayer:self.scanLayer.layer completion:^{
    }];
}

#pragma mark - Create QRCode Camera

- (void)addQRCodeCameraInterfaceWithBoxViewRect:(CGRect)rect {
    
    //获取摄像设备
    if (!self.device) {
        self.device = [self createDevice];
    }
    
    //创建输入流
    if (!self.input) {
        NSError *error = nil;
        self.input = [self createDeviceInputWithDevice:self.device error:error];
    }
    
    //创建输出流,并给定扫描范围
    if (!self.output) {
        CGRect rectOfInterest = [self getScanLayerRect:rect readerViewBounds:self.view.frame];
        self.output = [self createMetadataOutputWithRectOfInterest:rectOfInterest];
    }
    
    //初始化链接对象
    if (!self.session) {
        self.session = [self createAVCaptureSessionWithInput:self.input output:self.output];
    }
    
    if (self.session && self.output) {
        //完成输入流和输出流的对接后,开始设置输出流的支持类型，扫码支持的编码格式(如下设置条形码和二维码兼容)
        self.output.metadataObjectTypes = @[AVMetadataObjectTypeQRCode, AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode128Code];
    }
    //图象渲染层
    if (!self.previewLayer) {
        self.previewLayer = [self createVideoPreviewLayerWithSession:self.session showInLayer:self.view.layer];
    }
    
    //重新设置透明度
    UIImageView *img = (UIImageView *)[self.view viewWithTag:IMG_TAG];
    UIImage *image = [UIImage drawQRCodeBackgroundImageWithReferenceRect:img.bounds cropRect:self.boxRect alpha:0.5f];
    img.image = image;
    img.highlightedImage = image;
    
    //开始捕获
    [self startRunning];
}


- (void)startRunning {
    if (!self.session) {
        return;
    }
    [self.session startRunning];
}

- (void)stopRunning {
    if (!self.session) {
        return;
    }
    [self.session stopRunning];
}

- (CGRect)getScanLayerRect:(CGRect)rect readerViewBounds:(CGRect)readerViewBounds {
    
    return [self getScanLayerInViewForRect:rect readerViewBounds:readerViewBounds];
}


#pragma mark - Create Video Device Environmental

- (AVCaptureDevice *)createDevice {
    AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    return device;
}

- (AVCaptureDeviceInput *)createDeviceInputWithDevice:(AVCaptureDevice *)device error:(NSError *)error {
    AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error];
    return input;
}

- (AVCaptureMetadataOutput *)createMetadataOutputWithRectOfInterest:(CGRect)rectOfInterest {
    
    AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc] init];
    //扫描范围
    output.rectOfInterest = rectOfInterest;
    //设置代理 在主线程里刷新
    [output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
    return output;
}

- (AVCaptureVideoPreviewLayer *)createVideoPreviewLayerWithSession:(AVCaptureSession *)session showInLayer:(CALayer *)showInLayer {
    
    AVCaptureVideoPreviewLayer *previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:session];
    previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
    previewLayer.frame = self.view.layer.bounds;
    [showInLayer insertSublayer:previewLayer atIndex:0];
    
    return previewLayer;
}

- (AVCaptureSession *)createAVCaptureSessionWithInput:(AVCaptureDeviceInput *)input output:(AVCaptureMetadataOutput *)output {
    //初始化链接对象
    AVCaptureSession *session = [[AVCaptureSession alloc] init];
    //高质量采集率
    [session setSessionPreset:AVCaptureSessionPresetHigh];
    
    [session addInput:input];
    [session addOutput:output];
    
    return session;
}



#pragma mark - AVCaptureMetadataOutputObjectsDelegate

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection {
    
    if (metadataObjects.count>0) {
        
        [self stopRunning];
        AVMetadataMachineReadableCodeObject * metadataObject = [metadataObjects firstObject];
        NSLog(@"%@",metadataObject.stringValue);//输出扫描字符串
        
//        self.qrCodeString = metadataObject.stringValue;
        if (self.delegate && [self.delegate respondsToSelector:@selector(didOutputMetadataObject:)]) {
            [self.delegate didOutputMetadataObject:metadataObject.stringValue];
        }
        [self removeQRCodeAnimationInLayer:self.scanLayer.layer completion:^() {
        }];
    }
}


#pragma mark - Check Camera Available

- (BOOL)isCamera {
    return [self isCanUseCamera];
}

@end
